home *** CD-ROM | disk | FTP | other *** search
/ HTBasic 9.3 / HTBasic 9.3.iso / 93win / data1.cab / DLL_Toolkit / Source / HTBCalendar / YMSelector.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2005-03-02  |  16.3 KB  |  699 lines

  1. /**********************************************
  2. HTBCALENDAR.DLL
  3. TransEra Corporation 1999.
  4. This is the source for the HTBCalendar Dll.
  5. Class derived from Shekar Narayanan
  6. ***********************************************/
  7.  
  8. #include "stdafx.h"
  9. #include "YMSelector.h"
  10. #include <math.h>
  11.  
  12. #ifdef _DEBUG
  13. #define new DEBUG_NEW
  14. #undef THIS_FILE
  15. static char THIS_FILE[] = __FILE__;
  16. #endif
  17.  
  18. static char *Months[] =
  19. {
  20.     "January",
  21.     "February",
  22.     "March",
  23.     "April",
  24.     "May",
  25.     "June",
  26.     "July",
  27.     "August",
  28.     "September",
  29.     "October",
  30.     "November",
  31.     "December"
  32. };
  33.  
  34. static char *Weekdays[] =
  35. {
  36.     "S", "M", "T", "W", "T", "F", "S"
  37. };
  38.  
  39. static int DaysinMonth[] =
  40. {
  41.     31,28,31,30,31,30,31,31,30,31,30,31
  42. };
  43.  
  44. /////////////////////////////////////////////////////////////////////////////
  45. // CYMPopUp
  46.  
  47. CYMPopUp::CYMPopUp(CPoint p, CWnd* pParent, int nYear, int nMonth, int nDate) 
  48. : m_bkBrush(::GetSysColor(COLOR_INFOBK))
  49. {
  50.     if  (-1 == nYear)
  51.         m_nYear     = CTime::GetCurrentTime().GetYear();
  52.     else
  53.         m_nYear     = nYear;
  54.  
  55.     if  (-1 == nMonth)
  56.         m_nMonth    = CTime::GetCurrentTime().GetMonth() -1;
  57.     else
  58.         m_nMonth    = nMonth -1;
  59.  
  60.     if  (-1 == nDate)
  61.         m_nDate    = CTime::GetCurrentTime().GetDay() -1;
  62.     else
  63.         m_nDate    = nDate -1;
  64.  
  65.     ASSERT(m_nYear >= START_YEAR);
  66.     ASSERT(m_nMonth >= 0   && m_nMonth <= 11);
  67.     ASSERT(m_nDate >= 0   && m_nDate <= 30);
  68.  
  69.     // set number of rows and columns and margin
  70.     nRows = 8;
  71.     nColumns = 7;
  72.     nMargins = 4;
  73.     nStyle = TRADITIONAL_STYLE;
  74.  
  75.     Create(p, pParent);
  76. }
  77.  
  78. CYMPopUp::~CYMPopUp()
  79. {
  80.     m_bkBrush.DeleteObject();
  81. }
  82.  
  83.  
  84. BEGIN_MESSAGE_MAP(CYMPopUp, CWnd)
  85.     //{{AFX_MSG_MAP(CYMPopUp)
  86.     ON_WM_NCDESTROY()
  87.     ON_WM_LBUTTONUP()
  88.     ON_WM_PAINT()
  89.     ON_WM_LBUTTONDOWN()
  90.     ON_WM_KEYDOWN()
  91.     ON_WM_RBUTTONUP()
  92.     //}}AFX_MSG_MAP
  93. END_MESSAGE_MAP()
  94.  
  95.  
  96. /////////////////////////////////////////////////////////////////////////////
  97. // CYMPopUp message handlers
  98.  
  99.  
  100. BOOL CYMPopUp::Create(CPoint p, CWnd* pParent)
  101. {
  102.     m_pParent = pParent;
  103.     ASSERT(m_pParent);
  104.  
  105.     CString szClassName = AfxRegisterWndClass(CS_CLASSDC|CS_SAVEBITS|CS_HREDRAW|CS_VREDRAW,
  106.                                               0, (HBRUSH)m_bkBrush,0);
  107.  
  108.     if (!CWnd::CreateEx(0, szClassName, _T(""), WS_VISIBLE|WS_POPUP|WS_BORDER, 
  109.                         p.x, p.y, 250, 200, 
  110.                         pParent->GetSafeHwnd(), 0, NULL))
  111.         return FALSE;
  112.  
  113.     m_pParent->EnableWindow(false);
  114.  
  115.     UpdateWindow();
  116.  
  117.     return TRUE;
  118. }
  119.  
  120. void CYMPopUp::OnNcDestroy() 
  121. {
  122.     CWnd::OnNcDestroy();
  123.     delete this;
  124. }
  125.  
  126. int CYMPopUp::GetDaysinMonth()
  127. {
  128.     int nDays;
  129.     
  130.     nDays = DaysinMonth[m_nMonth];
  131.     if (LeapYear() && m_nMonth == 1) nDays++;
  132.     return (nDays);
  133. }
  134.  
  135. void CYMPopUp::OnPaint() 
  136. {
  137.     CPaintDC    dc(this);
  138.     CString     Buffer;
  139.     CRect       rClient;
  140.     CRect       rCell;
  141.     CRect       rStart;
  142.     CFont       fText;
  143.     CFont*      pfdc;
  144.     short       nIndex = 0;
  145.  
  146.     // get day associated with the first of the month
  147.     int nFirstDayofMonth = FDOM ();
  148.  
  149.     // get number of days in the month;
  150.     int nDays = GetDaysinMonth();
  151.     int nCellsNeeded = nDays + nFirstDayofMonth + 1;
  152.     //nRows = (nCellsNeeded - 1)/nColumns + 3;
  153.  
  154.     // get client dimensions
  155.     GetClientRect(rClient);
  156.  
  157.     // compute cell height and width
  158.     nCellHeight = (rClient.Height()-2*nMargins) / nRows;
  159.     nCellWidth  = (rClient.Width()-2*nMargins) / nColumns;
  160.  
  161.     // anchor point (top left)
  162.     CPoint nAnchor;
  163.     nAnchor.x = (rClient.Width() - nColumns*nCellWidth)/2;
  164.     nAnchor.y = (rClient.Height() - nRows*nCellHeight)/2;
  165.  
  166.     // decrement button
  167.     m_rMinus.left = nAnchor.x;
  168.     m_rMinus.right = m_rMinus.left + nCellWidth;
  169.     m_rMinus.top = nAnchor.y;
  170.     m_rMinus.bottom = m_rMinus.top + nCellHeight;
  171.  
  172.     // increment button
  173.     m_rPlus.right = rClient.right - nAnchor.x;
  174.     m_rPlus.left = m_rPlus.right - nCellWidth;
  175.     m_rPlus.top = nAnchor.y;
  176.     m_rPlus.bottom = m_rPlus.top + nCellHeight;
  177.  
  178.     // placeholder for current month and year
  179.     m_rYear.CopyRect(rClient);
  180.     m_rYear.left = m_rMinus.right + 5;
  181.     m_rYear.right = m_rPlus.left - 5;
  182.     m_rYear.top = nAnchor.y;
  183.     m_rYear.bottom = m_rYear.top + nCellHeight;
  184.  
  185.     fText.DeleteObject();
  186.     fText.CreatePointFont(120,"Times New Roman");
  187.     pfdc = dc.SelectObject(&fText);
  188.  
  189.     dc.SetBkColor(::GetSysColor(COLOR_INFOBK));
  190.     dc.SetTextColor(::GetSysColor(COLOR_INFOTEXT));
  191.  
  192.     // show current month and year
  193.     Buffer.Format("%s %d", Months[m_nMonth], m_nYear);
  194.     dc.DrawText(Buffer, m_rYear, DT_CENTER|DT_VCENTER|DT_SINGLELINE);
  195.  
  196.     // draw increment and decrement buttons
  197.     rStart.CopyRect(m_rMinus); rStart.right++;
  198.     dc.Rectangle (rStart);
  199.     rStart.CopyRect(m_rPlus); rStart.right++;
  200.     dc.Rectangle (rStart);
  201.  
  202.     dc.SetBkMode(TRANSPARENT);
  203.     dc.DrawText("-", m_rMinus, DT_CENTER|DT_VCENTER|DT_SINGLELINE);
  204.     dc.DrawText("+", m_rPlus, DT_CENTER|DT_VCENTER|DT_SINGLELINE);
  205.     dc.SetBkMode(OPAQUE);
  206.  
  207.     dc.SelectObject(pfdc);
  208.     fText.DeleteObject();
  209.     fText.CreatePointFont(FONT_SIZE,"MS Sans Serif");
  210.     pfdc = dc.SelectObject(&fText);
  211.     
  212.     // now draw the cells
  213.     rCell.left      = nAnchor.x;
  214.     rCell.top       = nAnchor.y + nCellHeight;
  215.     rCell.right     = rCell.left  + nCellWidth;
  216.     rCell.bottom    = rCell.top   + nCellHeight;
  217.  
  218.     // show the days of the week
  219.     rStart.CopyRect(rCell);
  220.     if (nStyle == TRADITIONAL_STYLE) {
  221.         dc.MoveTo (m_rMinus.left, rStart.bottom);
  222.         dc.LineTo (m_rPlus.right, rStart.bottom);
  223.     }
  224.  
  225.     for (int j = 0; j < 7; j++) {
  226.         if (nStyle == SIMPLE_STYLE) {
  227.             dc.MoveTo(rCell.left,rCell.top);
  228.             dc.LineTo(rCell.right,rCell.top);
  229.             dc.LineTo(rCell.right,rCell.bottom);
  230.  
  231.             dc.MoveTo(rCell.left,rCell.top);
  232.             dc.LineTo(rCell.left,rCell.bottom);
  233.         }
  234.         CRect   rCurSel(rCell);
  235.         rCurSel.DeflateRect(1,1);
  236.         dc.FillSolidRect(rCurSel,::GetSysColor(COLOR_INFOBK));
  237.         dc.SetTextColor(::GetSysColor(COLOR_INFOTEXT));
  238.         dc.DrawText(Weekdays[j], rCell, DT_VCENTER|DT_CENTER|DT_SINGLELINE);
  239.         rCell.OffsetRect(nCellWidth,0);
  240.     }
  241.     rStart.OffsetRect(0,nCellHeight);
  242.     rCell.CopyRect(rStart);
  243.  
  244.     BOOL bDone=FALSE;
  245.  
  246.     // show the dates (days of the month)
  247.     for (int i = 1; i < nRows-1; i++)
  248.     {
  249.         for (int j = 0; j < nColumns; j++)
  250.         {
  251.             if (nStyle == SIMPLE_STYLE) {
  252.                 dc.MoveTo(rCell.left,rCell.top);
  253.                 dc.LineTo(rCell.right,rCell.top);
  254.                 dc.LineTo(rCell.right,rCell.bottom);
  255.  
  256.                 dc.MoveTo(rCell.left,rCell.top);
  257.                 dc.LineTo(rCell.left,rCell.bottom); 
  258.                 dc.LineTo(rCell.right,rCell.bottom);
  259.             }
  260.  
  261.             CRect   rCurSel(rCell);
  262.             rCurSel.DeflateRect(1,1);
  263.  
  264.             // check whether the first of the month has been handled so far
  265.             if (!bDone && ((j+1) == nFirstDayofMonth || nFirstDayofMonth == 0))
  266.             {
  267.                 bDone = TRUE;
  268.                 dc.FillSolidRect(rCurSel,::GetSysColor(COLOR_INFOBK));
  269.                 rCell.OffsetRect(nCellWidth,0);
  270.             }
  271.             else if (bDone) {
  272.                 if  (m_nDate == nIndex)
  273.                 {
  274.                     dc.FillSolidRect(rCurSel,::GetSysColor(COLOR_HIGHLIGHT));
  275.                     dc.SetTextColor(::GetSysColor(COLOR_HIGHLIGHTTEXT));
  276.                 }
  277.                 else
  278.                 {
  279.                     dc.FillSolidRect(rCurSel,::GetSysColor(COLOR_INFOBK));
  280.                     dc.SetTextColor(::GetSysColor(COLOR_INFOTEXT));
  281.                 }
  282.  
  283.                 if (nIndex < nDays) {
  284.                     CString szT; szT.Format ("%2d",nIndex+1);
  285.                     dc.DrawText(szT, rCell, DT_VCENTER|DT_CENTER|DT_SINGLELINE);
  286.                     m_rCells[nIndex].CopyRect(rCell);
  287.                     nIndex++;
  288.                 }
  289.                 rCell.OffsetRect(nCellWidth,0);
  290.             }
  291.             else {
  292.                 dc.FillSolidRect(rCurSel,::GetSysColor(COLOR_INFOBK));
  293.                 rCell.OffsetRect(nCellWidth,0);
  294.             }
  295.         }
  296.  
  297.         rStart.OffsetRect(0,nCellHeight);
  298.         rCell.CopyRect(rStart);
  299.     }
  300.  
  301.     dc.SelectObject(pfdc);
  302.     fText.DeleteObject();
  303.  
  304. }
  305.  
  306. // -----------------------------------------------------------------------------
  307. void CYMPopUp::OnLButtonDown(UINT nFlags, CPoint point) 
  308. {
  309.     CClientDC   dc(this);
  310.     CWnd::OnLButtonDown(nFlags, point);
  311.  
  312.     for (int i = 0; i < GetDaysinMonth(); i++)
  313.     {
  314.         if  (m_rCells[i].PtInRect(point))
  315.         {
  316.             InvalidateRect(m_rCells[m_nDate]);
  317.             m_nDate = i;
  318.             InvalidateRect(m_rCells[i]);
  319.             return;
  320.         }
  321.     }
  322.  
  323.     if  (m_rMinus.PtInRect(point)) {
  324.         dc.InvertRect(m_rMinus);
  325.     }
  326.  
  327.     if  (m_rPlus.PtInRect(point)) {
  328.         dc.InvertRect(m_rPlus);
  329.     }
  330.  
  331. }
  332.  
  333. void CYMPopUp::OnLButtonUp(UINT nFlags, CPoint point) 
  334. {
  335.     CClientDC   dc(this);
  336.     CRect       rClient;
  337.  
  338.     if  (m_rMinus.PtInRect(point))
  339.     {
  340.         PreviousMonth ();
  341.         dc.InvertRect(m_rMinus);
  342.         Invalidate ();
  343.         return;
  344.     }
  345.  
  346.     if  (m_rPlus.PtInRect(point))
  347.     {
  348.         NextMonth();
  349.         dc.InvertRect(m_rPlus);
  350.         Invalidate ();
  351.         return;
  352.     }
  353.  
  354.     if  (ValidClick (point))
  355.     {
  356.         m_pParent->EnableWindow(true);
  357.         int nComposite = m_nDate + 100*(m_nMonth+1);
  358.         m_pParent->PostMessage(YM_SELECTED, (WPARAM)m_nYear, (LPARAM)nComposite);
  359.         DestroyWindow();
  360.     }
  361.  
  362. }
  363.  
  364. void CYMPopUp::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
  365. {
  366.     CWnd::OnKeyDown(nChar, nRepCnt, nFlags);
  367.     if (nChar == VK_ESCAPE) 
  368.     {
  369.         m_pParent->EnableWindow(true);
  370.         m_pParent->SendMessage(YM_ABORTED);
  371.         DestroyWindow();
  372.     }
  373.     else if (nChar == VK_LEFT) {
  374.         PreviousDay();
  375.         Invalidate();
  376.     }
  377.     else if (nChar == VK_RIGHT) {
  378.         NextDay();
  379.         Invalidate();
  380.     }
  381.     
  382. }
  383. // -----------------------------------------------------------------------------
  384.  
  385. void CYMPopUp::OnRButtonUp(UINT nFlags, CPoint point) // handles right mouse button clicks
  386.                                                       // in the + and - boxes
  387. {
  388.     CClientDC   dc(this);
  389.  
  390.     if  (m_rMinus.PtInRect(point)) 
  391.     {
  392.         m_nYear--;
  393.         dc.InvertRect(m_rMinus);
  394.         Invalidate ();
  395.         return;
  396.     }
  397.  
  398.     if  (m_rPlus.PtInRect(point))
  399.     {
  400.         m_nYear++;
  401.         dc.InvertRect(m_rPlus);
  402.         Invalidate ();
  403.         return;
  404.     }
  405.     
  406.     CWnd::OnRButtonUp(nFlags, point);
  407. }
  408.  
  409. BOOL CYMPopUp::ValidClick (CPoint point) // checks whether mouse click is in one of the
  410.                                          // cells containing a day of the current month
  411. {
  412.     for (int i = 0; i < GetDaysinMonth(); i++)
  413.     {
  414.         if  (m_rCells[i].PtInRect(point))
  415.             return TRUE;
  416.     }
  417.     return FALSE;
  418. }
  419.  
  420. void CYMPopUp::PreviousDay() // "sets" the previous day
  421. {
  422.     m_nDate--;
  423.     if (m_nDate < 0) {
  424.         m_nMonth--;
  425.         if (m_nMonth < 0) {
  426.             m_nMonth = 11;
  427.             m_nYear--;
  428.         }
  429.         m_nDate = GetDaysinMonth() - 1;
  430.     }
  431. }
  432.  
  433. void CYMPopUp::NextDay() // "sets" the next day
  434. {
  435.     m_nDate++;
  436.     if ((m_nDate+1) >  GetDaysinMonth()) {
  437.         m_nMonth++;
  438.         if (m_nMonth > 11) {
  439.             m_nMonth = 0;
  440.             m_nYear++;
  441.         }
  442.         m_nDate = 0;
  443.     }
  444. }
  445.  
  446. void CYMPopUp::PreviousMonth() // "sets" the previous month
  447. {
  448.     m_nMonth--;
  449.     if (m_nMonth < 0) {
  450.         m_nMonth = 11;
  451.         m_nYear--;
  452.     }
  453.     if ((m_nDate+1) > GetDaysinMonth()) m_nDate=0;
  454. }
  455.  
  456. void CYMPopUp::NextMonth()  // "sets" the next month
  457. {
  458.     m_nMonth++;
  459.     if (m_nMonth > 11) {
  460.         m_nMonth = 0;
  461.         m_nYear++;
  462.     }
  463.     if ((m_nDate+1) > GetDaysinMonth()) m_nDate=0;
  464. }
  465.  
  466. BOOL CYMPopUp::LeapYear () // is the current year a leap year?
  467. {
  468.     if ((m_nYear % 4 == 0 && m_nYear % 100 != 0) || (m_nYear % 400 == 0))
  469.         return (TRUE);
  470.     else
  471.         return (FALSE);
  472. }
  473.  
  474. int CYMPopUp::FDOM () // obtains the day of week for the first of the current month
  475. {
  476.     long jday = julday (m_nMonth+1, 1, m_nYear);
  477.     int idwk = (int) ((jday+1) % 7);
  478.  
  479.     return (idwk);
  480. }
  481.  
  482. #define IGREG (15+31L*(10+12L*1582)) // Gregorian Calendar (started in October 15, 1582)
  483.                                      // procedure to compute day of week available
  484.                                      // in Numerical Recipes in C, Press et. al.
  485.                                      // Cambridge Press
  486.  
  487. long CYMPopUp::julday (int mm, int id, int iyyy)
  488. {
  489.     long jul;
  490.     int ja, jy, jm;
  491.  
  492.     if (mm > 2) {
  493.         jy = iyyy;
  494.         jm = mm + 1;
  495.     }
  496.     else {
  497.         jy = iyyy - 1;
  498.         jm = mm + 13;
  499.     }
  500.     jul = (long) (floor(365.25*jy) + floor(30.6001*jm) + id + 1720995);
  501.     if (id + 31L*(mm+12L*iyyy) >= IGREG) {
  502.         ja = (int)(0.01f*jy);
  503.         jul += 2-ja+(int)(0.25*ja);
  504.     }
  505.     return jul;
  506. }
  507.  
  508. /////////////////////////////////////////////////////////////////////////////
  509. // CYMSelector
  510.  
  511. CYMSelector::CYMSelector()
  512. {
  513.     m_nMonth = CTime::GetCurrentTime().GetMonth();
  514.     m_nYear  = CTime::GetCurrentTime().GetYear();
  515.     m_nDate  = CTime::GetCurrentTime().GetDay();
  516. }
  517.  
  518. CYMSelector::~CYMSelector()
  519. {
  520. }
  521.  
  522.  
  523. BEGIN_MESSAGE_MAP(CYMSelector, CButton)
  524.     //{{AFX_MSG_MAP(CYMSelector)
  525.     ON_CONTROL_REFLECT(BN_CLICKED, OnClicked)
  526.     //}}AFX_MSG_MAP
  527.     ON_MESSAGE(YM_SELECTED, YMSelected)
  528.     ON_MESSAGE(YM_ABORTED,  YMAborted)
  529. END_MESSAGE_MAP()
  530.  
  531. /////////////////////////////////////////////////////////////////////////////
  532. // CYMSelector message handlers
  533.  
  534. void CYMSelector::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) 
  535. {
  536.     ASSERT(lpDrawItemStruct);
  537.  
  538.     CString BtnText;
  539.     CDC*    pDC     = CDC::FromHandle(lpDrawItemStruct->hDC);
  540.     CRect   rect    = lpDrawItemStruct->rcItem;
  541.     UINT    state   = lpDrawItemStruct->itemState;
  542.     
  543.     CRect   rArrow(rect);
  544.  
  545.     rArrow.left    = rArrow.right - 20;
  546.  
  547.     CSize Margins(::GetSystemMetrics(SM_CXEDGE), ::GetSystemMetrics(SM_CYEDGE));
  548.  
  549.     pDC->DrawFrameControl(&rArrow, DFC_SCROLL, DFCS_SCROLLDOWN  | 
  550.                           ((state & ODS_SELECTED) ? DFCS_PUSHED : 0) |
  551.                           ((state & ODS_DISABLED) ? DFCS_INACTIVE : 0));
  552.  
  553.  
  554.     rect.right -= rArrow.Width();
  555.  
  556.     pDC->FillSolidRect(rect,::GetSysColor(COLOR_WINDOW));
  557.  
  558.     GetWindowText(BtnText);
  559.     if  (state & ODS_DISABLED)
  560.         pDC->SetTextColor(::GetSysColor(COLOR_GRAYTEXT));
  561.     else
  562.         pDC->SetTextColor(::GetSysColor(COLOR_BTNTEXT));
  563.  
  564.     pDC->DrawText(BtnText, rect, DT_CENTER|DT_SINGLELINE|DT_VCENTER);
  565.  
  566.     if (state & ODS_FOCUS) 
  567.     {
  568.         rect.DeflateRect(1,1);
  569.         pDC->DrawFocusRect(rect);
  570.     }
  571.  
  572.     rect.InflateRect(1,1);
  573.     pDC->DrawEdge(rect,EDGE_BUMP,BF_RECT);
  574.  
  575.     
  576. }
  577.  
  578. void CYMSelector::PreSubclassWindow() 
  579. {
  580.     CButton::PreSubclassWindow();
  581.     CString buffer;
  582.     CTime   tCurrent = CTime::GetCurrentTime();
  583.     buffer = tCurrent.Format("%B %d, %Y");
  584.     SetWindowText(buffer);
  585.  
  586.     m_nYear  = tCurrent.GetYear();
  587.     m_nMonth = tCurrent.GetMonth() - 1;
  588.     m_nDate = tCurrent.GetDay() - 1;
  589. }
  590.  
  591. void CYMSelector::OnClicked() 
  592. {
  593.     CRect rect;
  594.     GetWindowRect(rect);
  595.     rect.OffsetRect(0,rect.Height());
  596.     GetParent()->EnableWindow(false);
  597.  
  598.     new CYMPopUp(CPoint(rect.left,rect.top), this,GetYear(),GetMonth(),GetDate());
  599.  
  600.     return;
  601.  
  602. }
  603.  
  604. LONG CYMSelector::YMSelected(WPARAM wParam , LPARAM lParam)
  605. {
  606.     m_nYear   = (int) wParam;
  607.     m_nMonth  = ((int) (lParam))/100 - 1;
  608.     m_nDate  = (int) lParam - 100*(m_nMonth+1);
  609.  
  610.     CString buffer;
  611.     buffer.Format("%s %d, %d", GetMonthString(), GetDate(), GetYear());
  612.     SetWindowText(buffer);
  613.     GetParent()->EnableWindow(true);
  614.     GetParent()->SetFocus();
  615.  
  616.     return 0;
  617. }
  618.  
  619. LONG CYMSelector::YMAborted(WPARAM wParam , LPARAM lParam)
  620. {
  621.     GetParent()->EnableWindow(true);
  622.     GetParent()->SetFocus();
  623.  
  624.     return 0;
  625. }
  626.  
  627. int CYMSelector::GetYear()
  628. {
  629.     return m_nYear;
  630. }
  631.  
  632. int CYMSelector::GetMonth()
  633. {
  634.     return m_nMonth + 1;
  635. }
  636.  
  637. int CYMSelector::GetDate()
  638. {
  639.     return m_nDate + 1;
  640. }
  641.  
  642. LPCTSTR CYMSelector::GetMonthString()
  643. {
  644.     return Months[m_nMonth];
  645. }
  646.  
  647. void CYMSelector::SetMonth(int m)
  648. {
  649.     m--;
  650.     ASSERT(m >= 0 && m <= 11);
  651.     m_nMonth = m;
  652.  
  653.     CString buffer;
  654.     buffer.Format("%s, %d", GetMonthString(), GetYear());
  655.     SetWindowText(buffer);
  656. }
  657.  
  658.  
  659. void CYMSelector::SetDate(int d)
  660. {
  661.     d--;
  662.     ASSERT(d < GetDaysinMonth());
  663.     m_nDate = d;
  664.  
  665.     CString buffer;
  666.     buffer.Format("%s %d, %d", GetMonthString(), GetDate(), GetYear());
  667.     SetWindowText(buffer);
  668. }
  669.  
  670.  
  671. void CYMSelector::SetYear(int y)
  672. {
  673.  
  674.     ASSERT(y >= START_YEAR);
  675.     m_nYear = y;
  676.  
  677.     CString buffer;
  678.     buffer.Format("%s %d, %d", GetMonthString(), GetDate(), GetYear());
  679.     SetWindowText(buffer);
  680. }
  681.  
  682. int CYMSelector::GetDaysinMonth()
  683. {
  684.     int nDays;
  685.     
  686.     nDays = DaysinMonth[m_nMonth];
  687.     if (LeapYear() && m_nMonth == 1) nDays++;
  688.     return (nDays);
  689. }
  690.  
  691. BOOL CYMSelector::LeapYear () // is the current year a leap year?
  692. {
  693.     if ((m_nYear % 4 == 0 && m_nYear % 100 != 0) || (m_nYear % 400 == 0))
  694.         return (TRUE);
  695.     else
  696.         return (FALSE);
  697. }
  698.  
  699.